﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using HNAlbum.Logic.Manager;

namespace HNAlbum.Logic.Entity
{
    /// <summary>
    /// Album blue print
    /// </summary>
    [XmlRoot("Album")]
    public class HNAlbumData : EntityBase
    {
        #region Constants
        public const string ALBUM_FILE = "Albums.xml";
        public const string PHOTO_FILE = "PhotoInfo.xml";
        public const string COVER_FILE = "Cover.jpg";
        #endregion

        #region Properties
        [XmlElement("Id", Order = 0)]
        public string Id { get; set; }

        [XmlElement("Name", Order = 1)]
        public string Name { get; set; }

        [XmlElement("Desc", Order = 2)]
        public string Description { get; set; }

        [XmlElement("Date", Order = 3)]
        public DateTime Date { get; set; }

        [XmlElement("By", Order = 4)]
        public string CreatedBy { get; set; }

        [XmlIgnoreAttribute]
        public string CoverImageUrl { get; set; }

        /// <summary>
        /// Photo(s) list
        /// </summary>
        [XmlIgnoreAttribute]
        public Dictionary<string, HNAlbumPhoto> PhotoCollection { get; set; }

        [XmlIgnoreAttribute]
        public AlbumInformation AlbumInfo { get; set; }

        [XmlIgnoreAttribute]
        public CreationSettings AlbumSettings { get; set; }
        #endregion

        #region Methods
        /// <summary>
        /// Default constructor for serialisation
        /// </summary>
        public HNAlbumData()
        {
            PhotoCollection = new Dictionary<string, HNAlbumPhoto>();
            AlbumSettings = new CreationSettings();
            AlbumInfo = new AlbumInformation();
        }
        /// <summary>
        /// Constructor accepts Album Id
        /// </summary>
        /// <param name="id"></param>
        public HNAlbumData(string id)
            : this()
        {
            Id = id;
        }

        /// <summary>
        /// Read the album data
        /// </summary>
        public void Load()
        {

            #region Read album info

            #region Try read album info XML
            XmlDocument xmlAlbumInfo = new XmlDocument();
            try
            {
                string albumXMLPath = Path.Combine(AppPhysicalPath, ApplicationFoler.XML, ALBUM_FILE);
                xmlAlbumInfo.Load(albumXMLPath);
            }
            catch (Exception ex)
            {
                LogAndThrow(ex, HNAException.Album.NotFound);
            }

            #endregion
            //Find album node with the same Id
            XmlNode nodeAlbum = xmlAlbumInfo.SelectSingleNode(string.Format("//Album[Id='{0}']", Id));
            //Then deserialize
            LoadXML(nodeAlbum.OuterXml);
            #endregion

            #region Read photos info

            #region Try read photo info XML
            XmlDocument xmlPhotoInfo = new XmlDocument();
            try
            {
                string photoXMLPath = Path.Combine(AppPhysicalPath, ApplicationFoler.Album, Id, PHOTO_FILE);
                xmlPhotoInfo.Load(photoXMLPath);
            }
            catch (Exception ex)
            {
                LogAndThrow(ex, HNAException.Album.NotFound);
            }
            #endregion

            XmlNodeList nodePhotos = xmlPhotoInfo.SelectNodes("//Photo");
            foreach (XmlNode node in nodePhotos)
            {
                HNAlbumPhoto photo = new HNAlbumPhoto();
                photo.LoadXML(node.OuterXml);
                photo.Url = Path.Combine("~", ApplicationFoler.Album, Id, HNAlbumPhoto.PHOTO_FOLDER, photo.PreviewName);
                photo.AlbumId = Id;
                PhotoCollection.Add(photo.Id, photo);
            }
            #endregion

            #region Populate info object
            AlbumInfo.Name = Name;
            AlbumInfo.Desc = Description;
            AlbumInfo.PhotoCount = PhotoCollection.Count.ToString();
            AlbumInfo.CreatedDate = Date.ToString("dd-MMM-yyyy HH:mm:ss");
            //Created by
            UserManager userMgr = new UserManager();
            HNAlbumUser user = userMgr.GetUser(CreatedBy);
            AlbumInfo.Author = user.Name;
            #endregion
        }
        #endregion

        #region Helper class
        /// <summary>
        /// Album info - mainly for JSON serialization
        /// </summary>
        public class AlbumInformation
        {
            public string Name { get; set; }
            public string Desc { get; set; }
            public string Author { get; set; }
            public string CreatedDate { get; set; }
            public string PhotoCount { get; set; }
        }
        /// <summary>
        /// How the album to be created
        /// </summary>
        public class CreationSettings
        {
            public bool CreateDefaultCaption { get; set; }
        }
        #endregion
    }
}
